﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.XPath;

namespace Songhay.Data.GenericWeb.InputDefinitions
{
    using Songhay.Data.GenericWeb.DataTransferContracts;
    using Songhay.Xml;

    /// <summary>
    /// Defines input for the Segment data transfer contract.
    /// </summary>
    public class InputSegment : ISegment
    {
        /// <summary>
        /// Processes data for the delete command.
        /// </summary>
        /// <param name="navigableInput">The navigable input.</param>
        /// <returns>Returns the Segment data transfer contract.</returns>
        public static ISegment InputDelete(IXPathNavigable navigableInput)
        {
            InputSegment inputSegment = new InputSegment();
            XPathNavigator node = XmlUtility.GetNavigableNode(navigableInput, "//FormData");

            int? id = FrameworkType.ParseInt32(XmlUtility.GetNodeValue(node, "./SegmentId", true));
            inputSegment.SegmentId = id;

            return inputSegment;
        }

        /// <summary>
        /// Processes data for the insert command.
        /// </summary>
        /// <param name="navigableInput">The navigable input.</param>
        /// <returns>Returns the Segment data transfer contract.</returns>
        public static ISegment InputInsert(IXPathNavigable navigableInput)
        {
            InputSegment inputSegment = new InputSegment();
            XPathNavigator node = XmlUtility.GetNavigableNode(navigableInput, "//FormData");

            object p = null;

            p = XmlUtility.GetNodeValue(node, "./SegmentName", true);
            inputSegment.SegmentName = FrameworkType.ParseString(p);

            p = XmlUtility.GetNodeValue(node, "./SortOrdinal", true);
            inputSegment.SortOrdinal = FrameworkType.ParseByte(p);

            p = XmlUtility.GetNodeValueAndParse<DateTime>(node, "./CreateDate", true, DateTime.Now);
            inputSegment.CreateDate = FrameworkType.ParseDateTime(p);

            p = XmlUtility.GetNodeValue(node, "./ParentSegmentId", true);
            inputSegment.ParentSegmentId = FrameworkType.ParseInt32(p);

            p = XmlUtility.GetNodeValue(node, "./ClientId", true);
            inputSegment.ClientId = FrameworkType.ParseString(p);

            p = XmlUtility.GetNodeValue(node, "./IsActive", true);
            inputSegment.IsActive = FrameworkType.ParseBoolean(p, true);

            return inputSegment;
        }

        /// <summary>
        /// Processes data for the update command.
        /// </summary>
        /// <param name="navigableInput">The navigable input.</param>
        /// <returns>Returns the Segment data transfer contract.</returns>
        public static ISegment InputUpdate(IXPathNavigable navigableInput)
        {
            XPathNavigator node = XmlUtility.GetNavigableNode(navigableInput, "//FormData");
            ISegment inputSegment = InputSegment.InputInsert(navigableInput);

            object p = null;

            p = XmlUtility.GetNodeValue(node, "./SegmentId", true);

            if(FrameworkType.ObjectIsNullOrEmptyString(p))
                throw new Exception("Segment ID cannot be null or empty.");

            inputSegment.SegmentId = FrameworkType.ParseInt32(p);

            if(inputSegment.SegmentId == inputSegment.ParentSegmentId)
                throw new Exception("Segment ID and parent Segment ID cannot be equal.");

            return inputSegment;
        }

        #region ISegment Members

        /// <summary>
        /// Gets or sets the Client ID.
        /// </summary>
        /// <value>The Client ID.</value>
        public string ClientId
        {
            get
            {
                return this._clientId;
            }
            set
            {
                this._clientId = value;
            }
        }

        /// <summary>
        /// Gets or sets the create date.
        /// </summary>
        /// <value>The create date.</value>
        public DateTime? CreateDate
        {
            get
            {
                return this._createDate;
            }
            set
            {
                this._createDate = value;
            }
        }

        /// <summary>
        /// Gets or sets whether the Segment is active.
        /// </summary>
        /// <value>The Segment is active?</value>
        public bool? IsActive
        {
            get
            {
                return this._isActive;
            }
            set
            {
                this._isActive = value;
            }
        }

        /// <summary>
        /// Gets or sets the parent Segment ID.
        /// </summary>
        /// <value>The parent Segment ID.</value>
        public int? ParentSegmentId
        {
            get
            {
                return this._parentSegmentId;
            }
            set
            {
                this._parentSegmentId = value;
            }
        }

        /// <summary>
        /// Gets or sets the Segment ID.
        /// </summary>
        /// <value>The Segment ID.</value>
        public int? SegmentId
        {
            get
            {
                return this._segmentId;
            }
            set
            {
                this._segmentId = value;
            }
        }

        /// <summary>
        /// Gets or sets the name of the Segment.
        /// </summary>
        /// <value>The name of the Segment.</value>
        public string SegmentName
        {
            get
            {
                return this._segmentName;
            }
            set
            {
                this._segmentName = value;
            }
        }

        /// <summary>
        /// Gets or sets the sort ordinal.
        /// </summary>
        /// <value>The sort ordinal.</value>
        public byte? SortOrdinal
        {
            get
            {
                return this._sortOrdinal;
            }
            set
            {
                this._sortOrdinal = value;
            }
        }

        #endregion

        private DateTime? _createDate = null;
        private bool? _isActive = null;
        private int? _parentSegmentId = null;
        private int? _segmentId = null;
        private string _segmentName = String.Empty;
        private byte? _sortOrdinal = null;
        private string _clientId = String.Empty;
    }
}
